﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SynoManager.Rss;
using System.Reflection;

namespace SynoManager.GUI
{
    /// <summary>
    /// Static class that can search CodePlex for new releases
    /// </summary>
    public static class UpdateChecker
    {
        private const string codePlexReleaseUrl = @"http://synomanager.codeplex.com/Project/ProjectRss.aspx?ProjectRSSFeed=codeplex%3a%2f%2frelease%2fSynoManager";

        /// <summary>
        /// Gets the updateinfo (if any)
        /// </summary>
        /// <returns>UpdateInfo with information about the latest release, or null if no new version is available.</returns>
        public static UpdateInfo CheckUpdate()
        {
            try
            {
                // Determine my version:
                Version localVersion = Assembly.GetExecutingAssembly().GetName().Version;

                RssFeed feed = RssFeed.Read(codePlexReleaseUrl); // Get Project Release feed @ CodePlex
                foreach (RssItem lastItem in feed.Channels[0].Items)
                {
                    // Determine online version:
                    string title = lastItem.Title; // Title of the latest release ()

                    if (!title.StartsWith("Released:"))
                        continue;

                    // title is in the form "Released: SynoManager 0.3 (Oct 03, 2008)" e.g.: "Updated Release: SynoManager <version> (<date>)"
                    string[] parts = title.Split(' ');
                    string onlineVersionString = parts[2];

                    Version onlineVersion = new Version(onlineVersionString);
                    if (onlineVersion > localVersion)
                    {
                        int semicolon = title.IndexOf(':') + 1;
                        int brace = title.LastIndexOf('(') - 1;
                        title = title.Substring(semicolon, brace - semicolon).Trim();
                        return new UpdateInfo(title, lastItem.Link.ToString(), lastItem.Description, lastItem.PubDate);
                    }
                    else
                    {
                        return null;
                    }
                }
                // none found?
                Debug.Fail("No Release found");
                return null;
            }
            catch(Exception ex)
            {
                Debug.WriteLine("Could not retrieve RSS Release log @ CodePlex", "UpdateChecker");
                return null;
            }
        }

        public static bool CheckUpdateAndShowWindow(IWin32Window owner)
        {
            UpdateInfo info = CheckUpdate();
            if (info == null)
            {
                MessageBox.Show(owner, "There is no new version available", "Check for Updates",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }

            UpdateForm form = new UpdateForm(info);
            form.ShowDialog(owner);
            return true;
        }

        public static bool AutoCheckUpdateAndShowWindow(IWin32Window owner)
        {
            // todo: in Backgroundworker
            if (Properties.Settings.Default.AutoCheckUpdates)
            {
                UpdateInfo info = CheckUpdate();
                if (info == null)
                {
                    return false;
                }
                else
                {                    
                    UpdateForm form = new UpdateForm(info);
                    form.ShowDialog(owner);
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        public class UpdateInfo
        {
            private readonly string title;
            private readonly string url;
            private readonly string info;
            private readonly DateTime date;

            public UpdateInfo(string title, string url, string info, DateTime date)
            {
                this.title = title;
                this.url = url;
                this.info = info;
                this.date = date;
            }

            public string Title
            {
                get { return title; }
            }

            public string Url
            {
                get { return url; }
            }

            public string Info
            {
                get { return info; }
            }

            public DateTime Date
            {
                get { return date; }
            }
        }
    }
}
